<?php

namespace App\Admin\Controllers;

use App\Http\Controllers\Controller;
use App\Modules\Doctor\Models\VideoCall;
use App\Modules\Doctor\Services\DiagnoseService;
use App\Modules\Doctor\Services\DoctorService;
use App\Modules\Index\Services\PrescriptionService;
use App\Modules\User\Services\UserService;
use Encore\Admin\Layout\Content;
use Encore\Admin\Facades\Admin;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Tencent\TLSSigAPIv2;


class DoctorController extends Controller
{
    //医生列表
    public function index(Request $request){
        $size = $request->input('size',11);
        $adminRoles = DB::table('admin_roles')->where('slug','doctor')->first();
        //查出医生用户列表
        $doctorIndex = DB::table('admin_role_users AS R')->select(['U.id','D.name','D.id AS d_id','D.tag','D.institution_id','D.department_id','D.contact','D.good_at','U.name AS u_name'])
                    ->leftJoin('admin_users AS U','R.user_id','=','U.id')
                    ->leftJoin('doctor AS D','U.id','=','D.admin_user_id')
                    ->where('R.role_id',$adminRoles->id)->paginate($size);
        //渲染视图
        return Admin::content(function (Content $content) use ($doctorIndex) {
            $content->body(view("doctor.index",['result'=>$doctorIndex]));
        });
    }

    /**
     * 工作台
     * @param Request $request
     * @return mixed
     */
    public function workbench(Request $request){
        $doctorIndex = [];
        $video_call=$request->input('video_call',0);
        $room = $request->input('room','');
        $trade_no = $request->input('trade_no','');
        $timestamp = $request->input('timestamp','');
        $duration = $request->input('duration','');
        $sign = $request->input('sign','');
        $sid = $request->input('sid','');
        $private_key =  env('INSIGHT_USER_SIGN');
        if($video_call && $sign) {
            $user_id = $sid?\Hashids::decode($sid)[0]:'';
            $doctor_admin_sid = $request->input('admin_sid',''); //视频通话打给的医生ID加密
            $doctor_admin_uid = \Hashids::decode($doctor_admin_sid)[0];
            \Log::info($doctor_admin_sid);
            \Log::info($doctor_admin_uid);

            $doc_user_id = Admin::user()->id; //当前登录管理后台用户ID
            \Log::info($doc_user_id);
            if($timestamp>time()||$timestamp<time()-3600 ||     //超过一小时才打开链接
                md5($room.$trade_no.$duration.$timestamp.$private_key.$sid.$doctor_admin_sid)!=$sign || //校验签名
                $doctor_admin_uid !=$doc_user_id    //是否是打给当前登录医生的视频电话
            ) {
                \Log::info('参数错误');
                \Log::info($sign);
                \Log::info(md5($room.$trade_no.$duration.$timestamp.$private_key.$sid.$doctor_admin_sid));
                //渲染视图
                return Admin::content(function (Content $content) use ($doctorIndex) {
                    $content->body(view("doctor.workbench",['result'=>$doctorIndex,'_error'=>'参数错误！','video_call'=>0]));
                });
            }
            $is_closed = \Redis::hGet('video_call_data:'.$user_id.':'.$trade_no.':'.$room.':','closed_by_peer');
            if(is_null($is_closed)) {
                $is_closed =  VideoCall::where('trade_no',$trade_no)->where('user_id',$user_id)->where('room_id',$room)->value('closed_by_peer');
            }
            if($is_closed) {
                return Admin::content(function (Content $content) use ($doctorIndex) {
                    $content->body(view("doctor.workbench",['result'=>$doctorIndex,'_error'=>'通话已结束！','video_call'=>0]));
                });
            }
            $camera_user_info = UserService::getById($user_id);
            $doc_uid= 'doc'.$doctor_admin_sid;
            //获取签名
            $api = new TLSSigAPIv2(env('TECENT_TRTC_APPID'), env('TENCENT_TRTC_SECRET'));
            $sig = $api->genSig($doc_uid,604800);
            $userSignConfig = [
                'userSgin'=>$sig,
                'sdkAppid'=>env('TECENT_TRTC_APPID')
            ];
            return Admin::content(function (Content $content) use ($doctorIndex,$room,$trade_no,$duration,$camera_user_info,$sign,$doc_uid,$userSignConfig,$doctor_admin_sid) {
                $content->body(view("doctor.workbench",['result'=>$doctorIndex,'video_call'=>1,'video_call_info'=>compact('room','trade_no','duration','camera_user_info','sign','doc_uid','userSignConfig','doctor_admin_sid')]));
            });
        }
        //渲染视图
        return Admin::content(function (Content $content) use ($doctorIndex) {
            $content->body(view("doctor.workbench",['result'=>$doctorIndex,'video_call'=>0]));
        });
    }

    //保存医生信息
    public function doctorUpdate(Request $request){
        $adminId = $request->input('id');
        if ( empty($adminId) ) return response()->error("PARAM_EMPTY");
        //判断当前用户ID是否属于医生
        $adminRoles = DB::table('admin_roles')->where('slug','doctor')->first();        //获取医生角色ID
        $userRoles = DB::table('admin_role_users')->where('user_id',$adminId)->first();;//获取当前用户所属的角色
        if ( $adminRoles->id != $userRoles->role_id ) return response()->error('PARAM_ERROR');
        $dataUpdateArr = [];
        !isset($_POST['name']) ? : $dataUpdateArr['name'] = $request->input('name','');
        !isset($_POST['institution_id']) ? : $dataUpdateArr['institution_id'] = $request->input('institution_id','');
        !isset($_POST['department_id']) ? : $dataUpdateArr['department_id'] = $request->input('department_id','');
        !isset($_POST['contact']) ? : $dataUpdateArr['contact'] = $request->input('contact','');
        !isset($_POST['good_at']) ? : $dataUpdateArr['good_at'] = $request->input('good_at','');
        !isset($_POST['tag']) ? : $dataUpdateArr['tag'] = $request->input('tag','');
        $dataUpdateArr['admin_user_id'] = $adminId;
        $doctorData = DoctorService::details('admin_user_id',$adminId);
        //判断是否存在，存在修改，不存在添加
        if ( empty($doctorData) ) {
            $result = DoctorService::addDoctor($dataUpdateArr);
        }else{
            $result = DoctorService::updateDoctor($dataUpdateArr);
        }
        if ( empty($result) ) return response()->error('UPDATE_FAILURE');
        return response()->success();
    }

    //处方审核
    public function adviceAudit(Content $content,Request $request)
    {
        $size = $request->input('size',11);
        //查询只是vip的
        $field = ['id','gender','name','birth_at',DB::raw('(select type FROM in_prescription where type = 1 and user_id = in_U.id limit 1) AS is_save')];
        $userData = DB::table('users AS U')->select($field)->where('vip',1)->orderBy('is_save','desc')->paginate($size);
        //渲染视图
        return Admin::content(function (Content $content) use ($userData) {
            $content->body(view("doctor.audit",['result'=>$userData]));
        });
    }

    /**
     * 个人资料
     */
     public function doctorInfo(){
         $userId= Auth::guard('admin')->user()->id;
         //根据当前登录id获取
         $doctorData = DoctorService::details('admin_user_id',$userId);
         //渲染视图
         return Admin::content(function (Content $content) use ($doctorData) {
             $content->body(view("doctor.info",['result'=>$doctorData]));
         });
     }

     /**
      * 添加/修改
      */
     public function doctorAddField(Request $request){
         $field = $request->input('field');
         $value = $request->input('value');
         $adminId= Auth::guard('admin')->user()->id;
         if ( empty($field) || !isset($_REQUEST['value']) ) return response()->error("PARAM_EMPTY");
         //判断当前用户ID是否属于医生
         $adminRoles = DB::table('admin_roles')->where('slug','doctor')->first();        //获取医生角色ID
         $userRoles = DB::table('admin_role_users')->where('user_id',$adminId)->first();;//获取当前用户所属的角色
         if ( $adminRoles->id != $userRoles->role_id ) return response()->error('PARAM_ERROR');
         //判断是否有数据
         $doctorData = DoctorService::details('admin_user_id',$adminId);
         $doctorArr = ['admin_user_id'=>$adminId,$field=>$value];
         if ( empty($doctorData) ) {
             $result = DoctorService::addDoctor($doctorArr);
         }else{
             //资质多个文件用逗号分开
             if ( $field == 'certificate' ) {
                 $status = true;
                 //判断当前的文件是否已经存在，存在是删除，不存在是添加
                 $certificate = explode(',',$doctorData->certificate);
                 foreach ( $certificate as $key => $item ) {
                     if ( $item == $value ) {
                         unset($certificate[$key]); //删除
                         $status = false;
                     }
                 }
                 //添加
                 if ( $status == true ) {
                     array_push($certificate,$value);
                 }
                 $doctorArr[$field] = implode(',',$certificate);
             }
             $result = DoctorService::updateDoctor($doctorArr);
         }
         if ( empty($result) ) return response()->error('UPDATE_FAILURE');
         return response()->success();
     }

     /**
      * 获取计量建议跟医疗建议
      */
     public function doctorAdvice(Request $request){
         $user_id = $request->input('user_id');
         if ( empty($user_id) ) return response()->error("PARAM_EMPTY");
         //获取最当前用户最后处方建议的数据（不展示拒绝审核的）
         $prescriptionGet = DB::table('prescription')->select(['id','group_id','type','status'])->where('user_id',$user_id)->where('status','!=',2)->orderBy('created_at','DESC')->first();
         if ( empty($prescriptionGet) ) {
             return response()->success();
         }
         //根据分组获取所有处方建议数据
         $field = ['id','meals','type','doctor_id','group_id','insulin_name_en','insulin_name_cn','insulin_type','insulin_preparation','adjustment_units','initial_units','final_units','audit_at','status'];
         $prescriptionData = DB::table('prescription')->select($field)->where('user_id',$user_id)->where('group_id',$prescriptionGet->group_id)->get()->map(function ($value) {
             return (array)$value;
         })->toArray();
         $prescriptionData = array_val_chunk($prescriptionData,['insulin_name_en','insulin_name_cn','insulin_type','insulin_preparation']);
         //获取用药建议
         if ( $prescriptionGet->status == 1 ) {
             $adviceMsg = DB::table('warning')->select(['id','content','content_en'])->where('user_id',$user_id)->where('group_id',$prescriptionGet->group_id)->where('type',2)->orderBy('created_at','DESC')->first();
         }
         //药品跟剂量相分离
         $itemArr = [];
         $itemKey = [];
         foreach ( $prescriptionData as $key => $value ) {
             $itemKey[$key] = $value[0];
             $itemArr[$key] = array_column($value,'final_units','meals');
         }
         //补缺少的数据
         foreach ( $itemArr as $key => $value ) {
             if ( empty($value[1]) ) $value[1] = '';
             if ( empty($value[2]) ) $value[2] = '';
             if ( empty($value[3]) ) $value[3] = '';
             if ( empty($value[4]) ) $value[4] = '';
             ksort($value);
             $itemArr[$key] = $value;
         }
         $data = [
             'advice'           => empty($adviceMsg->content) ? '' : $adviceMsg->content,
             'prescription'     => $itemArr,
             'prescription_key' => $itemKey,
             'group_id'         => $prescriptionGet->group_id
         ];
         return response()->success($data);
     }

     /**
      * 医生审核
      */
     public function doctorAudit(Request $request){
         $advice = $request->input('advice');
         $prescription_arr = $request->input('prescription_obj');
         $user_id = $request->input('user_id');
         $group_id = $request->input('group_id');
         if ( empty($advice) || empty($prescription_arr) || empty($user_id) || empty($group_id) ) return response()->error("PARAM_EMPTY");
         $adminId= Auth::guard('admin')->user()->id;
         //判断药品是否被修改
         DB::beginTransaction();
         try{
             foreach ( $prescription_arr as $key => $value ) {
                 //如果id为空表示新添加的
                 if ( empty($value['id']) ) {
                     foreach ( $value['meals'] as $k => $v ) {
                         if ( !empty($v['final_units']) && is_numeric($v['final_units']) ) {
                             $addMealsArr = [
                                 'user_id'              => $user_id,
                                 'meals'                => $v['meals'],
                                 'type'                 => 2,
                                 'group_id'             => $group_id,
                                 'doctor_id'            => $adminId,
                                 'insulin_name_en'      => $value['insulin_name_en'],
                                 'insulin_name_cn'      => $value['insulin_name_cn'],
                                 'insulin_type'         => $value['insulin_type'],
                                 'final_units'          => $v['final_units'],
                                 'insulin_preparation'  => $value['insulin_preparation'],
                                 'audit_at'             => date('Y-m-d H:i:s',time()),
                                 'status'               => 1
                             ];
                             $addStatus = PrescriptionService::addPrescription($addMealsArr);
                             if ( empty($addStatus) ) throw new \Exception('UPDATE_FAILURE');
                         }
                     }
                 }else{
                     //根据id获取到以前的药品数据
                     $insulinData = PrescriptionService::GetPrescriptions($value['id']);
                     if ( empty($insulinData) ) throw new \Exception('UPDATE_FAILURE');
                     //判断当前数据是否有修改
                     $where = ['insulin_name_en'=>$value['insulin_name_en'],'insulin_name_cn'=>$value['insulin_name_cn'],'insulin_preparation'=>$value['insulin_preparation'],'insulin_type'=>$value['insulin_type']];
                     $where['id'] = $value['id'];
                     $insulinIsSave = PrescriptionService::getPrescriptionOne($where);
                     //如果还存在，说明没有修改药品。如果不存在，则修改了药品
                     if ( empty($insulinIsSave) && !empty($value['id']) ) {
                         //修改药品名称
                         $nsulinWhere = [
                             'group_id'             => $insulinData->group_id,
                             'insulin_name_en'      => $insulinData->insulin_name_en,
                             'insulin_name_cn'      => $insulinData->insulin_name_cn,
                             'insulin_type'         => $insulinData->insulin_type,
                             'insulin_preparation'  => $insulinData->insulin_preparation,
                         ];
                         $saveArr = [
                             'insulin_name_en'      => $value['insulin_name_en'],
                             'insulin_name_cn'      => $value['insulin_name_cn'],
                             'insulin_type'         => $value['insulin_type'],
                             'insulin_preparation'  => $value['insulin_preparation'],
                         ];
                         $save = PrescriptionService::updateInsulin($nsulinWhere,$saveArr);
                         if ( empty($save) ) throw new \Exception('UPDATE_FAILURE');
                     }
                     unset($where['id']);
                     //判断早餐，中餐，晚餐，睡前的剂量是否有修改
                     foreach ( $value['meals'] as $k => $v ) {
                         $where['meals']    = $v['meals'];
                         $where['group_id'] = $value['group_id'];
                         //判断数据是否存在
                         $mealsData = PrescriptionService::getPrescriptionOne($where);
                         //如果存在，则修改。不存在时，如果剂量未0或者空，不做操作。如果剂量不为0或者空就添加
                         if ( !empty($mealsData) ) {
                             //存在，则修改
                             $saveMealsArr = [
                                 'type'             => 2,
                                 'doctor_id'        => $adminId,
                                 'final_units'      => $v['final_units'],
                                 'audit_at'         => date('Y-m-d H:i:s',time()),
                                 'status'           => 1
                             ];
                             $saveMealsStatus = PrescriptionService::updateInsulin($where,$saveMealsArr);
                             if ( empty($saveMealsStatus) ) throw new \Exception('UPDATE_FAILURE');
                         }else{
                             //不存在，如果剂量为0或者空，不做操作。如果剂量不为0或者空就添加
                             if ( !empty($v['final_units']) && is_numeric($v['final_units']) ) {
                                 $addMealsArr = [
                                     'user_id'              => $insulinData->user_id,
                                     'meals'                => $v['meals'],
                                     'type'                 => 2,
                                     'group_id'             => $insulinData->group_id,
                                     'doctor_id'            => $adminId,
                                     'insulin_name_en'      => $value['insulin_name_en'],
                                     'insulin_name_cn'      => $value['insulin_name_cn'],
                                     'insulin_type'         => $value['insulin_type'],
                                     'final_units'          => $v['final_units'],
                                     'insulin_preparation'  => $value['insulin_preparation'],
                                     'audit_at'             => date('Y-m-d H:i:s',time()),
                                     'status'               => 1
                                 ];
                                 $addStatus = PrescriptionService::addPrescription($addMealsArr);
                                 if ( empty($addStatus) ) throw new \Exception('UPDATE_FAILURE');
                             }
                         }
                     }
                 }
             }
             //将用户之前的处方建议全部设置为过期=>2
             $updateType = DB::table('prescription')->where('user_id',$user_id)->update(['type'=>2]);
             if ( empty($updateType) && $updateType !== 0 ) throw new \Exception('UPDATE_FAILURE');
             //添加医生建议
             $adviceArr = [
                 'user_id'      => $insulinData->user_id,
                 'group_id'     => $insulinData->group_id,
                 'content'      => $advice,
                 'type'         => 2,
                 'created_at'   => date('Y-m-d H:i:s',time()),
                 'updated_at'   => date('Y-m-d H:i:s',time()),
             ];
             $adviceStatus = DB::table('warning')->insert($adviceArr);
             if ( empty($adviceStatus) ) throw new \Exception('UPDATE_FAILURE');
             DB::commit();
         }catch (\Exception $e){
             DB::rollBack();
             return response()->error("UPDATE_FAILURE");
         }
         return response()->success();
     }

     /**
      * 拒绝审核
      */
     public function auditRefused(Request $request){
         $group_id = $request->input('group_id');
         if ( empty($group_id) ) return response()->error("PARAM_EMPTY");
         $adminId= Auth::guard('admin')->user()->id;
         $updateStatus = PrescriptionService::updateGroupPrescription(['group_id'=>$group_id,'type'=>2,'doctor_id'=>$adminId,'audit_at'=>date('Y-m-d H:i:s',time()),'status'=>2]);
         if ( empty($updateStatus) ) return response()->error("UPDATE_FAILURE");
         return response()->success();
     }

     /**
      * 历史用药建议
      */
     public function historyAdvice(Request $request){
         $user_id = $request->input('user_id');
         $created_at = $request->input('created_at','');
         $size = $request->input('size',11);
         if ( empty($user_id) ) {
             header("Location: /admin/doctor/audit");die;
         }
         //先根据分组id和药品名称 进行分组分页
         $sql = "(SELECT id,user_id,meals,group_id,insulin_name_cn,final_units,created_at FROM in_prescription where user_id = {$user_id}";
         if ( !empty($created_at) ) {
             $sql .= " AND created_at >= '{$created_at} 00:00:00' AND created_at <= '{$created_at} 23:59:59'";
         }
         $sql .= " GROUP BY group_id,insulin_name_cn) AS P";
         $adivaceData = DB::table(DB::raw($sql))->orderBy('id','DESC')->paginate($size);
//         p($adivaceData->items());
         foreach ( $adivaceData->items() as $key => $value ) {
             //查出每个分组下面的早、中、晚、睡前的详细数据
             $itme = DB::table('prescription')->select(['id','meals','final_units'])->where('group_id',$value->group_id)->where('insulin_name_cn',$value->insulin_name_cn)->get()->toArray();
             $itemArr = [];
             foreach ( $itme as $k => $v ) {
                 if ( $v->meals == 1 ) {
                     $itemArr['before_breakfast'] = $v->final_units;
                 }else if( $v->meals == 2 ) {
                     $itemArr['before_lunch'] = $v->final_units;
                 }else if( $v->meals == 3 ) {
                     $itemArr['before_dinner'] = $v->final_units;
                 }else if( $v->meals == 4 ) {
                     $itemArr['before_sleep'] = $v->final_units;
                 }
             }
             $adivaceData->items()[$key]->insulin = $itemArr;
         }
         //渲染视图
         return Admin::content(function (Content $content) use ($adivaceData) {
             $content->body(view("doctor.history",['result'=>$adivaceData]));
         });
     }

    /**
     * @param Request $request
     * @return mixed
     */
     public function connected_video(Request $request) {
         $uid = Admin::user()->id;
         $trade_no = $request->input('trade_no','');
         $room = $request->input('room','');
         $doctor_info = DoctorService::findByAdminUserId($uid);
         $video_call = VideoCall::where('trade_no',$trade_no)->where('doctor_id',$doctor_info->id)->where('room_id',$room)->first();
         $video_call->is_connected = 1;
         $video_call->start_time = date('Y-m-d H:i:s');
         $video_call->save();
         \Redis::hset('video_call_data:'.$video_call->user_id.':'.$trade_no.':'.$room.':','is_connected',1);
         return response()->success();
     }

     public function getDiagnoseInfo(Request $request) {
        $trade_no = $request->input('trade_no','');
        $diagnose = DiagnoseService::getDiagnoseByTradeNo($trade_no);
        $diagnose->video_call;
        return response()->success($diagnose);
     }
}